package edu.seu.mart.service.impl;

import edu.seu.mart.dao.IGoodsDao;
import edu.seu.mart.entity.Pager;
import edu.seu.mart.model.Goods;
import edu.seu.mart.model.Knowledge;
import edu.seu.mart.model.MartException;
import edu.seu.mart.model.User;
import edu.seu.mart.service.IGoodsService;
import org.apache.lucene.document.*;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.lucene.IKAnalyzer;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by zj on 2015/3/11.
 */
@Service
public class GoodsService implements IGoodsService {

    @Resource
    private IGoodsDao goodsDao;

    @Override
    public Pager<Goods> findGoods() {
        return goodsDao.findGoods();
    }

    @Override
    public Pager<Goods> findGoodsList(int i) {
        return goodsDao.findGoods(i);
    }

    @Override
    public Pager<Goods> findGoodsListBySellerId(int sellID, String flag) {
        return goodsDao.findGoodsListBySellerId(sellID, flag);
    }

    @Override
    public Pager<Goods> findGoodsByCategory(String name) {
        return  goodsDao.findGoodsByCategory(name);
    }

    @Override
    public Pager<Goods> findGoodsByCategory(String category, String brand, String price, String CPU, String SaleOrder, String priceOrder) {
        return goodsDao.findGoodsByCategory(category, brand,price,CPU,SaleOrder,priceOrder);
    }

    @Override
    public Pager<Goods> findGoods(String name) {
        return goodsDao.findGoods(name);
    }

    public Pager<Goods> findGoodsByNameOrBrand(String name) {
        return goodsDao.findGoodsByNameOrBrand(name);
    }

    @Override
    public Pager<Goods> findMatchedGoods(String query,String categroy,String saleOrder,String priceOrder) {
        return goodsDao.findMatchedGoods(query,categroy,saleOrder,priceOrder);
    }

    @Override
    public void add(Goods goods) {
        goodsDao.add(goods);
    }

    @Override
    public void delete(int id) {
        goodsDao.delete(id);
    }

    @Override
    public void delete(String[] ids) {
        try {
            for (String id : ids) {
                goodsDao.delete(Integer.valueOf(id));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void update(int id) {
        Goods goods = goodsDao.load(id);
        if (goods == null) throw new MartException("修改的商品不存在");
        goodsDao.update(goods);
    }

    @Override
    public void update(Goods goods) {
        goodsDao.update(goods);
    }

    @Override
    public Goods load(int id) {
        return goodsDao.load(id);
    }

    @Override
    public void updateStatus(int id) {
        Goods u = goodsDao.load(id);
        if (u == null) throw new MartException("修改状态的商品不存在");
        if (u.getStatus() == 0) {
            u.setStatus(1);
        } else if (u.getStatus() == 1) {
            u.setStatus(3);
        } else {
            u.setStatus(1);
        }
        goodsDao.update(u);
    }

    @Override
    public void deleteChecked(String[] ids) {
        try {
            for (String id : ids) {
                goodsDao.delete(Integer.valueOf(id));
            }
        } catch (Exception e) {
            throw new MartException("选中的商品删除失败");
        }
    }

    @Override
    public void updateUnPassStatus(int id) {
        Goods u = goodsDao.load(id);
        if (u == null) throw new MartException("修改状态的商品不存在");
        u.setStatus(2);
        goodsDao.update(u);
    }

    @Override
    public String getIndexDir() {
        String classpath = GoodsService.class.getResource("/").getPath();
        classpath = classpath.replaceAll("20%", " ");
        return classpath + "Goods/";
    }
    @Override
    public List<Goods> findAllGoods() {
        return goodsDao.findAllGoods();
    }
    @Override
    public void creatIndexDir() {
        List<Goods> GoodsList  = this.findAllGoods();
        Directory directory = null;
        IndexWriter indexWriter = null;
        try {
            directory = FSDirectory.open(new File(getIndexDir()));
            IndexWriterConfig iwConfig = new IndexWriterConfig(Version.LUCENE_46, new IKAnalyzer(true));
            indexWriter = new IndexWriter(directory, iwConfig);
            Document doc = null;
            for (Goods goods : GoodsList) {
                doc = new Document();
                doc.add(new TextField("name", goods.getName(), Field.Store.YES));
                doc.add(new IntField("id", goods.getId(), Field.Store.YES));
                doc.add(new TextField("RAM", goods.getRAM(), Field.Store.YES));
                doc.add(new TextField("CPU", goods.getCPU(), Field.Store.YES));
                doc.add(new TextField("HD", goods.getHD(), Field.Store.YES));
                doc.add(new TextField("brand", goods.getBrand(), Field.Store.YES));
                doc.add(new TextField("describer", goods.getDescriber(), Field.Store.YES));
                doc.add(new TextField("graphic", goods.getGraphic(), Field.Store.YES));
                doc.add(new DoubleField("price", goods.getPrice(), Field.Store.YES));
                doc.add(new TextField("category", goods.getCategory(), Field.Store.YES));
                doc.add(new TextField("sellerName", goods.getSeller().getName(), Field.Store.YES));

                indexWriter.addDocument(doc);
            }
            indexWriter.close();
            directory.close();
        } catch (IOException e) {
            throw new MartException(e);
        }
    }
    @Override
    public List<Goods> searchIndex(String content) {
        List<Goods> goodsList = new ArrayList<Goods>();
        try {
            Directory directory = FSDirectory.open(new File(this.getIndexDir()));
            IndexReader reader = IndexReader.open(directory);
            IndexSearcher searcher = new IndexSearcher(reader);
            String[] fields = { "name","RAM" ,"CPU","HD","brand","describer","graphic","category","sellerName"};
            Map<String, Float> boosts = new HashMap<String,Float>();
            boosts.put("name",10F);
            boosts.put("brand",8F);
            boosts.put("category",6F);
            boosts.put("describer",4F);
            boosts.put("CPU",1F);
            boosts.put("RAM",1F);
            MultiFieldQueryParser queryParser = new MultiFieldQueryParser(Version.LUCENE_46, fields,new IKAnalyzer(true),boosts);
//            QueryParser queryParser = new QueryParser(Version.LUCENE_46,"question", new IKAnalyzer(true));
            Query query = queryParser.parse(QueryParser.escape(content));
            TopDocs topDocs = searcher.search(query, 9);
            if (topDocs.totalHits > 0) {

                ScoreDoc[] scoreDocs = topDocs.scoreDocs;
                for (ScoreDoc sd : scoreDocs) {
                    Document doc = searcher.doc(sd.doc);
                    Goods goods =this.load(doc.getField("id").numericValue().intValue());
                    goodsList.add(goods);
                }
            }
            reader.close();
            directory.close();
        } catch (Exception e) {
            goodsList = null;
            e.printStackTrace();
        }
        return goodsList;
    }

    @Override
    public List<Goods> findRecommendGoods(int goodsId, String recommendType) {
        Goods goods = goodsDao.load(goodsId);
        String query = null;
        if (recommendType.equals("equalPrice")) {
            double price = goods.getPrice();
            query = (price - 500) + "-" + (price + 500);
        } else if (recommendType.equals("equalBrand")) {
            query = goods.getBrand();
        }
        return goodsDao.findRecommendGoods(query, goods.getCategory());
    }

}
